function ModuleVisaPlus(doc, container, width, height, user, date, options) {
  this._doc = doc;
  this._container = container;
  this._width = width;
  this._height = height;
  this._user = user;
  this._date = date;
  this._options = options;

  this._createElements();
};

ModuleVisaPlus.prototype._createElements = function() {
  this._client = null;
  this._loadData();
};

ModuleVisaPlus.prototype._loadData = function() {
  DOMUtils.removeChildElements(this._container);
  var img = document.createElement('img');
  img.src = 'image/loading.gif';
  this._container.appendChild(img);

  this._retrieveClient();
};

ModuleVisaPlus.prototype._verifyData = function() {
  if (this._client) {
    this._updateElements();
  }
};

ModuleVisaPlus.prototype._retrieveClient = function() {
  var _self = this;
  
  var visa = (this._options && this._options.object) ? this._options.object : pz_visa.instance();
  new RequestUtils()._read('pz_client', null, 'd.oid = \'' + visa.client_id + '\'', null, null, null, null, function(result, params) { _self._client = result.data[0];
                                                                                                                           _self._verifyData.call(_self);
                                                                                                                         }, null);
};

ModuleVisaPlus.prototype._updateElements = function() {
  this._gui = new VisaPlus(this._doc, this._container, this._width, this._height, this._user, this._date, this._options)._gui;
  var popupBox = (this._options && this._options.popupBox) ? this._options.popupBox : null;
  var callbackFunc = (this._options && this._options.callbackFunc) ? this._options.callbackFunc : function() {};
  
  var _self = this;
  this._gui.visa.onclick = function() { _self._options.mode = Constant.VPLUS_MODE_VISA;
                                        _self._updateElements.call(_self);
                                      };
  this._gui.client.onclick = function() { _self._options.mode = Constant.VPLUS_MODE_CLIENT;
                                          _self._updateElements.call(_self);
                                        };
                                        
  //Object
  var id = (this._options && this._options.id) ? this._options.id : null;
  var visa = (this._options && this._options.object) ? this._options.object : pz_visa.instance();
  if (!visa.id) {
    visa.client_id = id;
    visa.visa_date_expiry_current = 0;
    visa.visa_appl_date_submit = 0;
    visa.visa_date_issue = 0;
    visa.visa_date_expiry_new = 0;
    visa.visa_date_pickup = 0;
  }
  var mode = (this._options && this._options.mode) ? this._options.mode : Constant.VPLUS_MODE_VISA;
  if (mode == Constant.VPLUS_MODE_VISA) {
    new ModuleVisa(document, this._gui.more, null, null, _self._user, _self._date, { mode: Constant.VISA_MODE_PLUS, object: visa, popupBox: popupBox, callbackFunc: callbackFunc });
  } else if (mode == Constant.VPLUS_MODE_CLIENT) {
    new ModuleClientInfo(document, this._gui.more, null, null, _self._user, _self._date, { object: this._client, popupBox: popupBox, callbackFunc: callbackFunc });
  }
  //Submit
  //Notice: pz_visa is operated by mysqlcustom.php
  this._gui.save.onclick = function() { new RequestUtils()._write(JSON.stringify([{ n: 'pz_visa', a: [visa], r: [] }, { n: 'pz_client', a: [_self._client], r: [] }]), function(result, params) { callbackFunc(); popupBox._close(); }, { pos: DOMUtils.findPos(this) });
                                      };
  this._gui.cancel.onclick = function() { popupBox._close(); };
};
